package com.itheima.easy.face.impl;

import com.itheima.easy.adapter.FaceToFacePayAdapter;
import com.itheima.easy.constant.TradingCacheConstant;
import com.itheima.easy.enums.TradingEnum;
import com.itheima.easy.exception.ProjectException;
import com.itheima.easy.face.FaceToFacePayFace;
import com.itheima.easy.utils.ExceptionsUtil;
import com.itheima.easy.vo.TradingVo;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @Description 面对面支付Face接口实现
 */
@Slf4j
@Component
public class FaceToFacePayFaceImpl implements FaceToFacePayFace {
    @Autowired
    FaceToFacePayAdapter faceToFacePayAdapter;
    @Autowired
    RedissonClient redissonClient;

    /***
     * @description 生成交易付款码，待用户扫码付款
     * @param tradingVo 订单
     * @return  二维码路径
     */
    @GlobalTransactional
    public TradingVo precreateTrade(TradingVo tradingVo) {
        //1、对交易订单加锁
        Long productOrderNo = tradingVo.getProductOrderNo();
        String key = TradingCacheConstant.CREATE_PAY + productOrderNo;
        RLock lock = redissonClient.getFairLock(key);
        try {
            if (lock.tryLock(TradingCacheConstant.REDIS_WAIT_TIME, TimeUnit.SECONDS)){
                return faceToFacePayAdapter.precreateTrade(tradingVo);
            }else {
                throw new ProjectException(TradingEnum.TRAD_QRCODE_FAIL);
            }
        } catch (Exception e) {
            log.error("统一收单线下交易预创建异常:{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(TradingEnum.TRAD_QRCODE_FAIL);
        }finally {
            //释放锁
            lock.unlock();
        }
    }

    /***
     * @description 扫用户出示的付款码，完成付款
     * @param tradingVo 订单
     * @return  支付结果
     */
    public TradingVo payTrade(TradingVo tradingVo) {
        //1、对交易订单加锁
        Long productOrderNo = tradingVo.getProductOrderNo();
        String key = TradingCacheConstant.CREATE_PAY + productOrderNo;
        RLock lock = redissonClient.getFairLock(key);
        try {
            if (lock.tryLock(TradingCacheConstant.REDIS_WAIT_TIME, TimeUnit.SECONDS)){
                return faceToFacePayAdapter.payTrade(tradingVo);
            }else {
                throw new ProjectException(TradingEnum.TRAD_PAY_FAIL);
            }
        } catch (Exception e) {
            log.error("统一下单交易失败:{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(TradingEnum.TRAD_PAY_FAIL);
        }finally {
            //释放锁
            lock.unlock();
        }
    }

}
